﻿using AutoMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.JsonPatch;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Routing;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using TransformerManager.Shared.Helper;
using TransformerManager.API.Utils;
using TransformerManager.Shared.Dto.Accessories;
using TransformerManager.Shared.Dto.ActivePart;
using TransformerManager.Shared.Dto.BasicInfos;
using TransformerManager.Shared.Dto.Conservator;
using TransformerManager.Shared.Dto.CoolEquComp;
using TransformerManager.Shared.Dto.Lead;
using TransformerManager.Shared.Dto.Tank;
using TransformerManager.Shared.Dto.Transformer;
using TransformerManager.Shared.Dto.Winding;
using TransformerManager.EF.Models;
using TransformerManager.Shared.ResourceParameters;
using TransformerManager.Shared.Servers;
using TransformerManager.Shared.Helper.HttpParams;

namespace TransformerManager.API.Controllers
{

    [ApiVersion("1.0")]
    [Route("api/v{version:apiVersion}/[controller]")]
    [ApiController]
    public class TransformersController : ControllerBase
    {
        private readonly ITransformerRepository _transformerRepository;
        private readonly IMapper _mapper;
        private readonly IUrlHelper _urlHelper;

        public TransformersController(
            ITransformerRepository transformerRepository,
            IMapper mapper,
            IUrlHelperFactory urlHelperFactory,
            IActionContextAccessor actionContextAccessor)
        {
            _transformerRepository = transformerRepository;
            _mapper = mapper;
            _urlHelper = urlHelperFactory.GetUrlHelper(actionContextAccessor.ActionContext);
        }


        /// <summary>
        /// 根据产品区域计算数量
        /// </summary>
        /// <param name="regionType">产品区域</param>
        /// <param name="from">起始时间</param>
        /// <param name="end">截止时间</param>
        /// <returns></returns>
        [HttpGet("Number")]
        public async Task<IActionResult> GetTransformersNumByRegion(
            [FromQuery] string regionType,
            [FromQuery] DateTime from,
            [FromQuery] DateTime end)
        {
            int num = await _transformerRepository.GetTransformersNumAsync(regionType, from, end);
            return Ok(new ApiResponseParams(string.Empty, num));
        }

        /// <summary>
        /// 按检索要求获取指定数量的变压器列表
        /// </summary>
        /// <param name="trResourceParams">检索参数</param>
        /// <param name="paginationParams">分页参数</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPost("Query", Name = "GetTransformers")]
        [HttpHead]
        public async Task<IActionResult> GetTransformers(
            [FromBody] TransformerResourceParameters trResourceParams,
            [FromQuery] PaginationResourceParameters paginationParams)
        {
            var transformersFromRepo = await _transformerRepository.GetTransformersAsync(
                trResourceParams, paginationParams);

            if (transformersFromRepo == null || transformersFromRepo.Count() <= 0)
            {
                return NotFound(new ApiResponseParams("没有检索到变压器信息"));
            }

            var transformersDto = _mapper.Map<IEnumerable<TransformerDto>>(transformersFromRepo);

            // 生成前一页的URL
            var previousPageLink = transformersFromRepo.HasPrevious ?
                HttpUtils.GenerateRouteResourceURL(
                    paginationParams,
                    "GetTransformers",
                    ResourceUrlType.PreviousPage,
                    _urlHelper) : null;

            // 生成后一页的URL
            var nextPageLink = transformersFromRepo.HasNext ?
                HttpUtils.GenerateRouteResourceURL(
                    paginationParams,
                    "GetTransformers",
                    ResourceUrlType.NextPage,
                    _urlHelper) : null;

            var paginationMetadata = new
            {
                previousPageLink,
                nextPageLink,
                totalCount = transformersFromRepo.TotalCount,
                pageSize = transformersFromRepo.PageSize,
                currentPage = transformersFromRepo.CurrentPage,
                totalPages = transformersFromRepo.TotalPages
            };

            // 通过Response的头部信息返回hatos成熟度3等级的restful头信息
            Response.Headers.Add("x-pagination",
                Newtonsoft.Json.JsonConvert.SerializeObject(paginationMetadata));

            return Ok(new ApiResponseParams(string.Empty, transformersDto));
        }

        /// <summary>
        /// 通过GUID查询数据
        /// </summary>
        /// <param name="transformerId">变压器的GUID</param>
        /// <returns></returns>
        [HttpGet("{transformerId:Guid}", Name = "GetTransformerFromId")]
        public async Task<IActionResult> GetTransformerFromId(Guid transformerId)
        {
            var transformerFromRepo = await _transformerRepository.GetTransformerAsync(transformerId);

            if (transformerFromRepo == null)
            {
                return NotFound(new ApiResponseParams($"{transformerId} 变压器找不到"));
            }

            var transformerDto = _mapper.Map<TransformerDto>(transformerFromRepo);

            return Ok(new ApiResponseParams(string.Empty, transformerDto));
        }

        /// <summary>
        /// 核查项目号是有效
        /// </summary>
        /// <param name="projectNumber">项目号</param>
        /// <returns></returns>
        [HttpGet("{projectNumber}")]
        public async Task<IActionResult> CheckTransformerProjectValid(string projectNumber)
        {
            if (!await _transformerRepository.CheckTransformerExistByProjectNumberAsync(projectNumber))
            {
                return Ok(new ApiResponseParams(string.Empty));
            }
            return Conflict(new ApiResponseParams($"项目号: {projectNumber}已存在"));
        }

        /// <summary>
        /// 创建变压器数据
        /// </summary>
        /// <param name="transformerForCreationDto">创建产品参数</param>
        /// <returns></returns>

        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPost]
        public async Task<IActionResult> CreateTransformer([FromBody] TransformerForCreationDto transformerForCreationDto)
        {
            var transformerModel = _mapper.Map<TransformerForCreationDto, Transformer>(transformerForCreationDto);

            _transformerRepository.AddTransformer(transformerModel);
            await _transformerRepository.SaveChangesAsync();

            var transformerDto = _mapper.Map<TransformerDto>(transformerModel);

            return Created("GetTransformerFromId", new ApiResponseParams($"创建项目 V{transformerDto.BasicInfos.ProjectNumber}成功"));

            //return CreatedAtAction(
            //    "GetTransformerFromId",
            //    transformerDto.Id,
            //    transformerDto);
        }

        #region 更新数据

        /// <summary>
        /// 更新变压器所有数据
        /// </summary>
        /// <param name="transformerId">变压器的GUID</param>
        /// <param name="transformerForUpdateDto">完整的更新参数</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPut("{transformerId}")]
        public async Task<IActionResult> UpdateTransformerParams(
            [FromRoute] Guid transformerId,
            [FromBody] TransformerForUpdateDto transformerForUpdateDto)
        {
            if (!await _transformerRepository.CheckTransformerExistAsync(transformerId))
            {
                return NotFound(new ApiResponseParams($"当前Id={transformerId}的变压器找不到"));
            }

            var transformerModel = await _transformerRepository.GetTransformerAsync(transformerId);

            _mapper.Map(transformerForUpdateDto, transformerModel);

            await _transformerRepository.SaveChangesAsync();
            
            return Ok(new ApiResponseParams($"更新V{transformerModel.BasicInfos.ProjectNumber}的数据成功!"));
        }

        /// <summary>
        /// 更新变压器的基本数据
        /// </summary>
        /// <param name="transformerId">变压器的GUID</param>
        /// <param name="basicInfosForUpdateDto">需要更新的基本数据</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPut("BasicInfos/{transformerId}")]
        public async Task<IActionResult> UpdateBasicInfosParams(
            [FromRoute] Guid transformerId,
            [FromBody] BasicInfosForUpdateDto basicInfosForUpdateDto)
        {
            if (!await _transformerRepository.CheckTransformerExistAsync(transformerId))
            {
                return NotFound(new ApiResponseParams($"当前Id={transformerId}的变压器找不到"));
            }

            var basicInfosModel = await _transformerRepository.GetBasicInfosAsync(transformerId);

            _mapper.Map(basicInfosForUpdateDto, basicInfosModel);

            await _transformerRepository.SaveChangesAsync();

            return Ok(new ApiResponseParams($"当前项目的BasicInfos数据更新成功!"));
        }

        /// <summary>
        /// 更新变压器的油箱所有数据
        /// </summary>
        /// <param name="transformerId">变压器的GUID</param>
        /// <param name="tankForUpdateDto">油箱的更新数据</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPut("Tank/{transformerId}")]
        public async Task<IActionResult> UpdateTankParams(
            [FromRoute] Guid transformerId,
            [FromBody] TankForUpdateDto tankForUpdateDto)
        {
            if (!await _transformerRepository.CheckTransformerExistAsync(transformerId))
            {
                return NotFound(new ApiResponseParams($"当前Id={transformerId}的变压器找不到"));
            }

            var tankModel = await _transformerRepository.GetTankAsync(transformerId);

            _mapper.Map(tankForUpdateDto, tankModel);

            await _transformerRepository.SaveChangesAsync();

            return Ok(new ApiResponseParams($"当前的Tank数据更新成功!"));
        }

        /// <summary>
        /// 更新储油柜的所有数据
        /// </summary>
        /// <param name="transformerId">变压器的GUID</param>
        /// <param name="conservatorForUpdateDto">储油柜的更新数据</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPut("Conservator/{transformerId}")]
        public async Task<IActionResult> UpdateConservatorParams(
            [FromRoute] Guid transformerId,
            [FromBody] ConservatorForUpdateDto conservatorForUpdateDto)
        {
            if (!await _transformerRepository.CheckTransformerExistAsync(transformerId))
            {
                return NotFound(new ApiResponseParams($"当前Id={transformerId}的变压器找不到"));
            }

            var conservatorModel = await _transformerRepository.GetConservatorAsync(transformerId);

            _mapper.Map(conservatorForUpdateDto, conservatorModel);

            await _transformerRepository.SaveChangesAsync();

            return Ok(new ApiResponseParams($"当前的Conservator数据更新成功!"));
        }

        /// <summary>
        /// 更新冷却系统的所有数据
        /// </summary>
        /// <param name="transformerId">变压器的GUID</param>
        /// <param name="coolingSystemForUpdateDto">冷却系统的更新数据</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPut("CoolingSystem/{transformerId}")]
        public async Task<IActionResult> UpdateCoolingSystemParams(
            [FromRoute] Guid transformerId,
            [FromBody] CoolingSystemForUpdateDto coolingSystemForUpdateDto)
        {
            if (!await _transformerRepository.CheckTransformerExistAsync(transformerId))
            {
                return NotFound(new ApiResponseParams($"当前Id={transformerId}的变压器找不到"));
            }

            var coolingSystemModel = await _transformerRepository.GetCoolingSystemAsync(transformerId);

            _mapper.Map(coolingSystemForUpdateDto, coolingSystemModel);

            await _transformerRepository.SaveChangesAsync();

            return Ok(new ApiResponseParams($"当前的CoolingSystem数据更新成功!"));
        }

        /// <summary>
        /// 更新附件的所有数据
        /// </summary>
        /// <param name="transformerId">变压器的GUID</param>
        /// <param name="accessoriesForUpdateDto">附件的更新数据</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPut("Accessories/{transformerId}")]
        public async Task<IActionResult> UpdateAccessoriesParams(
            [FromRoute] Guid transformerId,
            [FromBody] AccessoriesForUpdateDto accessoriesForUpdateDto)
        {
            if (!await _transformerRepository.CheckTransformerExistAsync(transformerId))
            {
                return NotFound(new ApiResponseParams($"当前Id={transformerId}的变压器找不到"));
            }

            var accessoriesModel = await _transformerRepository.GetAccessoriesAsync(transformerId);

            _mapper.Map(accessoriesForUpdateDto, accessoriesModel);

            await _transformerRepository.SaveChangesAsync();

            return Ok(new ApiResponseParams($"当前的Accessories数据更新成功!"));
        }

        /// <summary>
        /// 更新引线的所有数据
        /// </summary>
        /// <param name="transformerId">变压器的GUID</param>
        /// <param name="leadForUpdateDto">引线的更新数据</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPut("Lead/{transformerId}")]
        public async Task<IActionResult> UpdateLeadParams(
            [FromRoute] Guid transformerId,
            [FromBody] LeadForUpdateDto leadForUpdateDto)
        {
            if (!await _transformerRepository.CheckTransformerExistAsync(transformerId))
            {
                return NotFound(new ApiResponseParams($"当前Id={transformerId}的变压器找不到"));
            }

            var leadModel = await _transformerRepository.GetLeadAsync(transformerId);

            _mapper.Map(leadForUpdateDto, leadModel);

            await _transformerRepository.SaveChangesAsync();

            return Ok(new ApiResponseParams($"当前的Lead数据更新成功!"));
        }

        /// <summary>
        /// 更新线圈的所有数据
        /// </summary>
        /// <param name="transformerId">变压器的GUID</param>
        /// <param name="windingForUpdateDto">线圈的更新数据</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPut("Winding/{transformerId}")]
        public async Task<IActionResult> UpdateWindingParams(
            [FromRoute] Guid transformerId,
            [FromBody] WindingForUpdateDto windingForUpdateDto)
        {
            if (!await _transformerRepository.CheckTransformerExistAsync(transformerId))
            {
                return NotFound(new ApiResponseParams($"当前Id={transformerId}的变压器找不到"));
            }

            var windingModel = await _transformerRepository.GetWindingAsync(transformerId);

            _mapper.Map(windingForUpdateDto, windingModel);

            await _transformerRepository.SaveChangesAsync();

            return Ok(new ApiResponseParams($"当前的Winding数据更新成功!"));
        }

        /// <summary>
        /// 更新器身的所有数据
        /// </summary>
        /// <param name="transformerId">变压器的GUID</param>
        /// <param name="activePartForUpdateDto">器身的更新数据</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPut("ActivePart/{transformerId}")]
        public async Task<IActionResult> UpdateActivePartParams(
            [FromRoute] Guid transformerId,
            [FromBody] ActivePartForUpdateDto activePartForUpdateDto)
        {
            if (!await _transformerRepository.CheckTransformerExistAsync(transformerId))
            {
                return NotFound(new ApiResponseParams($"当前Id={transformerId}的变压器找不到"));
            }

            var activePartModel = await _transformerRepository.GetActivePartAsync(transformerId);

            _mapper.Map(activePartForUpdateDto, activePartModel);

            await _transformerRepository.SaveChangesAsync();

            return Ok(new ApiResponseParams($"当前的ActivePart数据更新成功!"));
        }

        /// <summary>
        /// 部分参数更新
        /// </summary>
        /// <param name="transformerId">变压器的GUID</param>
        /// <param name="patchDocument">部分更新的参数</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPatch("{transformerId}")]
        public async Task<IActionResult> PartiallyUpdateTransformer(
             [FromRoute] Guid transformerId,
            [FromBody] JsonPatchDocument<TransformerForUpdateDto> patchDocument)
        {
            if (!await _transformerRepository.CheckTransformerExistAsync(transformerId))
            {
                return NotFound(new ApiResponseParams($"当前Id={transformerId}的变压器找不到"));
            }

            var transformerFromRepo = await _transformerRepository.GetTransformerAsync(transformerId);

            var transformerForPatchDto = _mapper.Map<TransformerForUpdateDto>(transformerFromRepo);

            patchDocument.ApplyTo(transformerForPatchDto, ModelState);

            if (!TryValidateModel(transformerForPatchDto))
            {
                return ValidationProblem(ModelState);
            }

            _mapper.Map(transformerForPatchDto, transformerFromRepo);

            await _transformerRepository.SaveChangesAsync();

            return Ok(new ApiResponseParams($"Id={transformerId}的变压器数据更新成功!"));
        }

        #endregion

        /// <summary>
        /// 从数据库中删除指定GUID的变压器信息
        /// </summary>
        /// <param name="transformerId"></param>
        /// <returns></returns>
        [Authorize(Roles = "Admin, SuperAdmin")]
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpDelete("{transformerId}")]
        public async Task<IActionResult> DeleteTransformer(
            [FromRoute] Guid transformerId)
        {
            if (!await _transformerRepository.CheckTransformerExistAsync(transformerId))
            {
                return NotFound(new ApiResponseParams($"当前Id={transformerId}的变压器找不到"));
            }

            var transformerFromRepo = _transformerRepository.GetTransformerAsync(transformerId);

            _transformerRepository.DeleteTransformer(transformerFromRepo.Result);

            await _transformerRepository.SaveChangesAsync();
            
            return Ok(new ApiResponseParams($"成功删除V{transformerFromRepo.Result.BasicInfos.ProjectNumber}的数据!"));
        }


        /// <summary>
        /// 根据产品GUID批量删除变压器信息
        /// </summary>
        /// <param name="ids">变压器的GUID</param>
        /// <returns></returns>
        [Authorize(Roles = "Admin, SuperAdmin")]
        [Authorize(AuthenticationSchemes = "Bearer")] //jwt的身份验证，必须显示添加bearer方式验证
        [HttpDelete]
        public async Task<IActionResult> DeleteTransformers([FromQuery] string ids)
        {
            string[] idArray = ids.Split(",");
            List<Guid> guids = new List<Guid>();
            foreach (var id in idArray)
            {
                guids.Add(Guid.Parse(id));
            }
            IEnumerable<Guid> transformerGuids = guids.AsEnumerable<Guid>();

            IEnumerable<Transformer> transformersFromRepo = await _transformerRepository.GetTransformerByIdsAsync(transformerGuids);

            if (transformersFromRepo == null || transformersFromRepo.Count() == 0)
            {
                return BadRequest(new ApiResponseParams("批量删除变压器数据失败!"));
            }

            _transformerRepository.DeleteTransformers(transformersFromRepo);
            await _transformerRepository.SaveChangesAsync();

            return Ok(new ApiResponseParams($"成功批量删除Id为 {ids} 的变压器数据。"));

        }
    }
}
